/* Copyright (C) 2010 Fredrique Samuels, fredriquesamuels@gmail.com 

 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation, either version 3 of the License, or
 (at your option) any later version.

 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.

 You should have received a copy of the GNU General Public License
 along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

//Include library header
#include "shapes.h"

namespace tri{

GLUquadricObj *TShape::mQuadricObj = NULL;

TShape::TShape(): tri::TEntity(){
	createGlobalQuadricObj();
}

TShape::~TShape(){}

void TShape::display(){}

void TShape::createGlobalQuadricObj(){
	if(TShape::mQuadricObj==NULL){
		TShape::mQuadricObj = gluNewQuadric();							// Create A New Quadratic
		gluQuadricNormals(TShape::mQuadricObj, GL_SMOOTH);				// Generate Smooth Normals For The Quad
		gluQuadricTexture(TShape::mQuadricObj, GL_TRUE);				// Enable Texture Coords For The Quad
	}
}


//===========================================

TSphere::TSphere() :TShape(),mSlices(16),mStacks(16){}
TSphere::~TSphere(){}

void TSphere::display(){
	
	glPushMatrix();
	TVector size = getSize();
	glScalef(size.x,size.y,size.z);
	tri::TTexture* tex = getMaterialPointer()->getTexture();
	if (tex != NULL){
		tex->bind();
	}
	getMaterialPointer()->getColor().apply();
	gluSphere(TShape::mQuadricObj, 0.5f, mSlices, mStacks);
	glPopMatrix();
	
}

void TSphere::setStacks(int s){
	mStacks = s;
}

void TSphere::setSlices(int s){
	mSlices = s;
}

TCube::TCube() :TShape(){}
TCube::~TCube(){}

static void
drawBox(float w, float h, float l)
{
	GLfloat cube_normals[6][3] = {  /* Normals for the 6 faces of a cube. */
			  {-1.0, 0.0, 0.0}, {0.0, 1.0, 0.0}, {1.0, 0.0, 0.0},
			  {0.0, -1.0, 0.0}, {0.0, 0.0, 1.0}, {0.0, 0.0, -1.0} };
	GLint cube_faces[6][4] = {  /* Vertex indices for the 6 faces of a cube. */
	  {0, 1, 2, 3}, {3, 2, 6, 7}, {7, 6, 5, 4},
	  {4, 5, 1, 0}, {5, 6, 2, 1}, {7, 4, 0, 3} };
	GLfloat cube_vertices[8][3] = {{-0.5,-0.5,0.5},
			                                      {-0.5,-0.5,-0.5},
			                                      {-0.5,0.5,-0.5},
			                                      {-0.5,0.5,0.5},
			                                      {0.5,-0.5,0.5},
			                                      {0.5,-0.5,-0.5},
			                                      {0.5,0.5,-0.5},
			                                      {0.5,0.5,0.5}};
	
	glScaled(w,h,l);
    for (int i = 0; i < 6; i++) {
	    glBegin(GL_QUADS);
	    glNormal3fv(&cube_normals[i][0]);
	    glTexCoord2f(1,0);
	    glVertex3fv(&cube_vertices[cube_faces[i][3]][0]);
	    glTexCoord2f(1,1);
	    glVertex3fv(&cube_vertices[cube_faces[i][2]][0]);
	    glTexCoord2f(0,1);
	    glVertex3fv(&cube_vertices[cube_faces[i][1]][0]);
	    glTexCoord2f(0,0);
	    glVertex3fv(&cube_vertices[cube_faces[i][0]][0]);
	    glEnd();
    }

//  for (i = 5; i >= 0; i--) {
//    glBegin(type);
//    glNormal3fv(&n[i][0]);
//    
//    glTexCoord2f(1,0);
//    glVertex3fv(&v[faces[i][3]][0]);
//   
//    glTexCoord2f(1,1);
//	glVertex3fv(&v[faces[i][2]][0]);
//	
//    glTexCoord2f(0,1);
//    glVertex3fv(&v[faces[i][1]][0]);
//	
//	glTexCoord2f(0,0);
//    glVertex3fv(&v[faces[i][0]][0]);
//    
//    glEnd();
//  }
}


void TCube::display(){
	
	glPushMatrix();
	TVector size = getSize();
	tri::TTexture* tex = getMaterialPointer()->getTexture();
	if (tex != NULL){
		tex->bind();
	}
	getMaterialPointer()->getColor().apply();
	tri::applyTexture(getImage());
	
	glPushMatrix();
	glScalef(0.5*size.x,0.5*size.y,0.5*size.z);
	
	glBegin(GL_QUADS);									
	// Front Face
	glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f,  1.0f);
	glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, -1.0f,  1.0f);
	glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f,  1.0f,  1.0f);
	glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f,  1.0f,  1.0f);
	// Back Face
	glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f, -1.0f);
	glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f,  1.0f, -1.0f);
	glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f,  1.0f, -1.0f);
	glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f, -1.0f);
	// Top Face
	glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f,  1.0f, -1.0f);
	glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f,  1.0f,  1.0f);
	glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f,  1.0f,  1.0f);
	glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f,  1.0f, -1.0f);
	// Bottom Face
	glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f, -1.0f, -1.0f);
	glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f, -1.0f, -1.0f);
	glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f,  1.0f);
	glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f,  1.0f);
	// Right face
	glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, -1.0f, -1.0f);
	glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f,  1.0f, -1.0f);
	glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f,  1.0f,  1.0f);
	glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f,  1.0f);
	// Left Face
	glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f, -1.0f);
	glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f,  1.0f);
	glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f,  1.0f,  1.0f);
	glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f,  1.0f, -1.0f);
	glEnd();	
	glPopMatrix();
	glPopMatrix();
	
}

}
